package edu.xmut.yuepaibackend.service.impl;

import java.math.BigDecimal;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import cn.hutool.core.net.NetUtil;
import edu.xmut.yuepaibackend.model.domain.*;
import edu.xmut.yuepaibackend.model.form.BlogPublishForm.TagsDTO;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.xmut.yuepaibackend.model.form.BlogPublishForm;
import edu.xmut.yuepaibackend.model.vo.*;
import edu.xmut.yuepaibackend.service.*;
import edu.xmut.yuepaibackend.mapper.BlogMapper;
import edu.xmut.yuepaibackend.utils.BeanCopyUtils;
import edu.xmut.yuepaibackend.utils.IDGenerator;
import edu.xmut.yuepaibackend.utils.IpUtils;
import edu.xmut.yuepaibackend.utils.UserContext;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author tanjiao
 * @description 针对表【blog(帖子)】的数据库操作Service实现
 * @createDate 2024-09-06 14:52:19
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog>
        implements BlogService {

    @Autowired
    private UserService userService;

    @Autowired
    private CommentService commentService;

    @Resource
    private SysPictureService sysPictureService;

    @Resource
    private IpUtils ipUtils;

    @Resource
    private BlogTagsService blogTagsService;

    @Override
    public PageVO recommend(Integer pageNum, Integer pageSize) {
        Page<Blog> blogPage = new Page<>(pageNum, pageSize);
        Page<Blog> page = this.lambdaQuery()
                .orderBy(true, false, Blog::getPublishTime)
                .page(blogPage);
        List<BlogRecommendVO> collect = page.getRecords().stream()
                .map(blog -> {
                    BlogRecommendVO blogRecommendVO = new BlogRecommendVO();
                    blogRecommendVO.setId(blog.getId().toString());
                    BlogRecommendVO.BlogCard blogCard = new BlogRecommendVO.BlogCard();
                    SimpleUserVO user = new SimpleUserVO();
                    Long userId = blog.getUserId();
                    User userFromDB = userService.getById(userId);
                    user.setUserId(userId);
                    user.setAvatar(userFromDB.getAvatar());
                    user.setNickname(userFromDB.getNickname());
                    blogCard.setType(blog.getType());
                    blogCard.setUser(user);
                    blogCard.setCover(blog.getCover());
                    blogCard.setDisplayTitle(blog.getTitle());
                    BlogInteractInfoVO blogInteractInfoVO = new BlogInteractInfoVO();
                    blogInteractInfoVO.setLiked(true);
                    blogInteractInfoVO.setLikedCount(10);
                    blogCard.setInteractInfo(blogInteractInfoVO);
                    blogRecommendVO.setBlogCard(blogCard);
                    return blogRecommendVO;
                }).toList();
        PageVO data = PageVO.builder()
                .pageSize(pageSize)
                .pageNum(pageNum)
                .records(collect)
                .total(page.getTotal())
                .build();
        return data;
    }


    @Override
    public BlogDetailVo getBlogDetail(Long id) {
        BlogDetailVo blogDetailVo = new BlogDetailVo();
        blogDetailVo.setId(id);
        BlogDetailVo.BlogDetail detail = new BlogDetailVo.BlogDetail();
        Blog blog = getById(id);
        detail.setType(blog.getType());
        detail.setTitle(blog.getTitle());
        detail.setContent(blog.getContent());
        detail.setPublishTime(blog.getPublishTime());
        // 判断是图文还是视频
        if (blog.getType().equals(0)) {
            // 从图片数据库中查出关联的图片URL
            List<SysPicture> pictureList = sysPictureService.lambdaQuery()
                    .eq(SysPicture::getBlogId, id)
                    .orderBy(true, true, SysPicture::getSort)
                    .list();
            List<PictureVO> pictureVOList = pictureList.stream()
                    .map((item) -> BeanUtil.copyProperties(item, PictureVO.class))
                    .toList();
            detail.setPicUrl(pictureVOList);
        } else if (blog.getType().equals(1)) {
            String videoUrl = blog.getVideoUrl();
            if (StrUtil.isNotBlank(videoUrl)) {
                detail.setVideoUrl(videoUrl);
            }
        }
        // 查询IP属地
        String ipRegion = ipUtils.getIpRegion(blog.getIp());
        detail.setIp(ipRegion);
        // 封装作者
        SimpleUserVO user = new SimpleUserVO();
        Long userId = blog.getUserId();
        User userFromDB = userService.getById(userId);
        user.setUserId(userId);
        user.setAvatar(userFromDB.getAvatar());
        user.setNickname(userFromDB.getNickname());
        BlogInteractInfoVO blogInteractInfoVO = new BlogInteractInfoVO();
        blogInteractInfoVO.setLiked(true);
        blogInteractInfoVO.setLikedCount(10);
        BlogDetailVo.BlogComment comment = new BlogDetailVo.BlogComment();
        List<Comment> commentList = commentService.getCommentByBlogId(id);
        // 创建一个列表来存储转换后的BlogCommentVo对象
        List<BlogCommentVo> blogCommentVoList = new ArrayList<>();
        commentList.forEach(c -> {
            BlogCommentVo blogCommentVo = new BlogCommentVo();
            blogCommentVo.setId(Long.valueOf(c.getId()));
            blogCommentVo.setContent(c.getContent());
            blogCommentVo.setCreateTime(c.getCreateTime());
            blogCommentVo.setBlogId(c.getBlogId());
            // 封装评论用户
            Long commentUserId = c.getUserId();
            User commentUser = userService.getById(commentUserId);
            SimpleUserVO simpleUserVO = new SimpleUserVO();
            BeanCopyUtils.fillSimpleUserVO(simpleUserVO, commentUser);
            blogCommentVo.setUser(simpleUserVO);
            blogCommentVoList.add(blogCommentVo);
        });
        // 将BlogCommentVo列表设置到BlogDetailVo.BlogComment对象中
        comment.setComment(blogCommentVoList);
        // 最后，将BlogComment对象设置到BlogDetailVo中
        blogDetailVo.setBlogComment(comment);
        blogDetailVo.setInteractInfo(blogInteractInfoVO);
        blogDetailVo.setBlogDetail(detail);
        blogDetailVo.setAuthor(user);
        return blogDetailVo;
    }

    @Override
    public Long publish(BlogPublishForm blogPublishForm, HttpServletRequest request) {
        String title = blogPublishForm.getTitle();
        String content = blogPublishForm.getContent();
        BigDecimal longitude = blogPublishForm.getLongitude();
        BigDecimal latitude = blogPublishForm.getLatitude();
        String address = blogPublishForm.getAddress();
        String fullAddress = blogPublishForm.getFullAddress();
        List<String> imageIds = blogPublishForm.getImageIds();
        List<TagsDTO> tags = blogPublishForm.getTags();
        // 1.得到用户id
        Long userId = UserContext.getUserId();
        // 2.构造实体类
        Blog blog = new Blog();
        // 生成ID
        long id = IDGenerator.nextId();
        blog.setId(id);
        blog.setUserId(userId);
        blog.setTitle(title);
        blog.setContent(content);
        blog.setLat(latitude);
        blog.setLon(longitude);
        // 3.关联地址
        blog.setAddress(address);
        blog.setFulladdress(fullAddress);
        // 4.获取远程IP
        String ip = IpUtils.getIpAddress(request);
        blog.setIp(ip);
        blog.setPublishTime(DateUtil.date());
        // 5.关联图片地址
        if (CollectionUtil.isNotEmpty(imageIds)) {
            // 批量插入图片数据
            int index = 0;
            for (String imageId : imageIds) {
                sysPictureService.lambdaUpdate()
                        .set(SysPicture::getBlogId, id)
                        .set(SysPicture::getSort, index)
                        .eq(SysPicture::getId, imageId)
                        .update();
                index++;
            }
        }
        // 设置保存封面
        SysPicture cover = sysPictureService.lambdaQuery().eq(SysPicture::getId, imageIds.get(0)).one();
        blog.setCover(cover.getPreviewUrl());
        // 6.保存关联的标签
        for (TagsDTO tag : tags) {
            BlogTags blogTags = new BlogTags();
            blogTags.setBlogId(id);
            blogTags.setTagId(tag.getId());
            blogTagsService.save(blogTags);
        }
        // 7.保存动态主体
        this.save(blog);
        return id;
    }
}




